/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       text_edit_window.cpp

	$Header: /game/text_edit_window.cpp $

	$NoKeywords: $

 ************************************************************************/
// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "text_edit_window.h"

#include "abstract_bitmap.h"
#include "font.h"
#include "game_time.h"
#include "idle_processor.h"
#include "override_input_handler.h"
#include "mouse_event.h"
#include "paint_surface.h"

namespace
{
	// --------------------------------------------------------------
	// simple, blinking vertical line
	// --------------------------------------------------------------
	class t_caret_window : public t_window, public t_idle_processor
	{
	public:
		t_caret_window( t_screen_rect const& rect, t_window* parent, t_pixel_24 const & color = t_pixel_24(0,0,0) );
		void			set_color( t_pixel_24 color );

		virtual void on_idle();
		virtual void paint( t_paint_surface& paint_surface );
	protected:
		int			m_draw;
	private:
		t_pixel_24	m_color;
	};

	void t_caret_window::set_color( t_pixel_24 color )
	{
		m_color = color;
	}
};


// --------------------------------------------------------------
// simple, blinking vertical line
// --------------------------------------------------------------
t_caret_window::t_caret_window( t_screen_rect const& rect, t_window* parent, t_pixel_24 const & color )
              : t_window( rect, k_some_transparency, parent ),
			    t_idle_processor(0, 500), m_color( color )
{
	m_draw = true;
}

// --------------------------------------------------------------
// simple, blinking vertical line
// --------------------------------------------------------------
void t_caret_window::on_idle()
{
	m_draw = !m_draw;
	invalidate();
}

// --------------------------------------------------------------
// simple, blinking vertical line
// --------------------------------------------------------------
void t_caret_window::paint( t_paint_surface& paint_surface )
{
	if (!m_draw)
		return;

	t_abstract_bitmap16_ptr	dest = paint_surface.get_bitmap();
	t_screen_rect           rect = paint_surface.get_screen_rect();

	rect = intersection( rect, get_screen_rect() );
	if (rect.width() <= 0 || rect.height() <= 0)
		return;

	rect -= rect.top_left();
	fill( *dest, rect, m_color );
}


// --------------------------------------------------------------
// text edit window class
// --------------------------------------------------------------
t_text_edit_window::t_text_edit_window( t_cached_font& font, t_screen_rect const& rect,
									    t_window* parent, std::string const& text, 
						                t_pixel_24 const& color )
				  : t_text_window( font, rect, parent, text, color )
{
	m_caret_column = 0;
	m_caret_row = 0;
	m_caret_string_position = 0;
	m_caret_window = 0;
	m_editing = false;
	m_enabled = true;
	m_rows = rect.height() / m_font->get_height();
	m_color = color;
}

// --------------------------------------------------------------
// text edit window class
// --------------------------------------------------------------
void t_text_edit_window::delete_char()
{
	if (m_caret_string_position >= m_text.size())
		return;

	std::string text;

	if (m_caret_string_position > 0)
		text = m_text.substr( 0, m_caret_string_position );
	if (m_caret_string_position + 1 < m_text.size())
		text += m_text.substr( m_caret_string_position + 1 );
	set_text( text );
}

// --------------------------------------------------------------
// text edit window class
// --------------------------------------------------------------
void t_text_edit_window::on_keyboard_focus_lost()
{
	if (m_editing)
	{
		m_editing = false;
		m_caret_window->set_visible( false );
	}
}

// --------------------------------------------------------------
// text edit window class
// --------------------------------------------------------------
void t_text_edit_window::begin_edit()
{
	if (!m_enabled)
		return;
	m_caret_string_position = 0;
	if (m_caret_window == 0)
		build_caret_window();
	position_caret();
	m_caret_window->set_visible( true );
	m_editing = true;
	set_keyboard_focus();
}

void t_text_edit_window::left_button_down( t_mouse_event const& event )
{
}

// --------------------------------------------------------------
// text edit window class
// --------------------------------------------------------------
void t_text_edit_window::left_button_up( t_mouse_event const& event )
{
	
	int			   i;
	int            column;
	int            row;
	t_screen_point row_start;

	if (!m_enabled)
		return;
	row = event.client_point.y / m_font->get_height();
	if (row >= m_rows)
		row = m_rows - 1;
	row_start = get_row_start( row );
	column = event.client_point.x - row_start.x;
	if (row < m_text_block.size())
		m_caret_string_position = m_font->get_column( m_text_block[row].c_str(), column );
	else 
	{
		row = m_text_block.size();
		m_caret_string_position = 0;
	}
	for (i = 0; i < row; i++)
		m_caret_string_position += m_text_block[i].size();
	if (m_caret_window == 0)
		build_caret_window();
	position_caret();
	m_caret_window->set_visible( true );
	m_editing = true;
	set_keyboard_focus();
}

// --------------------------------------------------------------
// text edit window class
// --------------------------------------------------------------
void t_text_edit_window::on_size_change( t_screen_rect const& rect )
{
	t_text_window::on_size_change( rect );
	m_rows = rect.height() / m_font->get_height();
}

// --------------------------------------------------------------
// text edit window class
// --------------------------------------------------------------
void t_text_edit_window::build_caret_window()
{
	if (m_caret_window != 0)
	{
		m_caret_window->close();
		m_caret_window = 0;
	}
	t_screen_rect rect( 0, 0, 2, m_font->get_height() );

	m_caret_window = new t_caret_window( rect, this, m_color );
}

// --------------------------------------------------------------
// text edit window class
// --------------------------------------------------------------
void t_text_edit_window::on_text_change()
{
	m_rows = get_client_rect().height() / m_font->get_height();
	if (m_editing)
		position_caret();
}

// --------------------------------------------------------------
// text edit window class
// --------------------------------------------------------------
void t_text_edit_window::position_caret()
{
	t_screen_point point;
	int            column;

	// determine row, column
	m_caret_row = 0;
	column = m_caret_string_position;
	while (m_caret_row + 1 < m_text_block.size() && column > m_text_block[m_caret_row].size())
	{
		column -= m_text_block[m_caret_row].size();
		m_caret_row++;
	}
	point = get_row_start( m_caret_row );
	if (m_text_block.size() > 0)
		point.x += m_font->get_width( m_text_block[m_caret_row].substr( 0, column ).c_str() );
	m_caret_window->move( point );
}

